home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr37 / satsfaxt.zip / CCPUTILS.ZIP / CCSAVEX.C < prev    next >
C/C++ Source or Header  |  1990-01-30  |  16KB  |  382 lines

  1. /*---------------------------------------------------------------------------*
  2.  *                 CCSAVEX.C                     *
  3.  *---------------------------------------------------------------------------*
  4.  * The program allows the user to move a file received from an Intel         *
  5.  * Connection CoProcessor to a normal MS-DOS file. The file can be moved     *
  6.  * to any pre-existing path on any disk drive.                     *
  7.  *                                         *
  8.  * The following source code is intended to assist developers in         *
  9.  * creating applications which support the  DCA/Intel Communicating         *
  10.  * Applications Specification Version 1.0A. It is provided free of charge    *
  11.  * and on an as-is basis. THE IMPLIED WARRENTIES OF MERCHANTABILITY AND      *
  12.  * FITNESS FOR A PARTICULAR PURPOSE ARE SPECIFICALLY EXCLUDED. This source   *
  13.  * code may be modified, enhanced, copied and distributed with applications  *
  14.  * that support CAS on a royalty free basis.                     *
  15.  *---------------------------------------------------------------------------*/
  16. #include <stdio.h>
  17. #include <dos.h>
  18. #include <io.h>
  19. #include <malloc.h>
  20. #include <string.h>
  21. #include "cas.h"            /* Intel CAS header file.             */
  22. #include "parse.h"            /* Command line parser header file.      */
  23. #include "util.h"            /* CAS utilities header file.         */
  24.  
  25. int MoveAll = FALSE;            /* Save all received files.          */
  26. int Confirm = FALSE;            /* Confirm before moving file.         */
  27. int Verbose = FALSE;            /* List file names as they are moved.    */
  28. int Delete = FALSE;            /* Delete event after saving files.      */
  29. int JobNo = 0;                /* Job number to move.             */
  30. int Help = FALSE;            /* Show help text.                 */
  31. int RedirOut = FALSE;            /* Redirect output to file.          */
  32. int FilesMoved = FALSE;         /* TRUE if something was saved.         */
  33.  
  34. ECF *TCFbuffer;             /* Task Control File buffer.         */
  35. FTR *FTRbuffer;             /* File Transfer Record buffer.         */
  36. FILE *ccout;                /* Redirected stdout file.             */
  37.  
  38. STABLE SwitchTable [] =         /* Command line parser switch table.     */
  39. {
  40.     { 'A', BOOL, &MoveAll  },
  41.     { 'a', BOOL, &MoveAll  },
  42.     { 'C', BOOL, &Confirm  },
  43.     { 'c', BOOL, &Confirm  },
  44.     { 'D', BOOL, &Delete   },
  45.     { 'd', BOOL, &Delete   },
  46.     { 'N', BOOL, &Verbose  },
  47.     { 'n', BOOL, &Verbose  },
  48.     { 'E', INT,  &JobNo    },
  49.     { 'e', INT,  &JobNo    },
  50.     { 'R', BOOL, &RedirOut },
  51.     { 'r', BOOL, &RedirOut },
  52.     { '?', BOOL, &Help       }
  53. };
  54. #define TABLESIZE (sizeof(SwitchTable)/sizeof(STABLE))
  55.  
  56. char *DescTable[] =        /* Help function description table. */
  57. {
  58.     "CCSAVEX (V1.0) Saves (and deletes from the queue) a file transfer received\n",
  59.     "from a Connection CoProcessor.\n\n",
  60.     "The file can be saved to any existing  directory on any disk drive (for\n",
  61.     "example, c:\\reports). If you specify the /A option, CCSAVEX will save ALL\n",
  62.     "file transfers in the receive queue to the specified directory.\n\n",
  63.     "Syntax: CCSAVEX /Exxxxx directory [option...]\n\n"
  64. };
  65. #define DESCSIZE (sizeof(DescTable)/sizeof(DescTable[0]))
  66.  
  67. char *HelpTable[] =        /* Help function text table. */
  68. {
  69.      "  /A           Move all received files to \"directory\". If the file\n",
  70.      "               exists, you'll be prompted for overwrite permission.\n",
  71.      "  /E<number>   Save file transfer(s) associated with the event specified\n",
  72.      "               by <number>.\n\n",
  73.      "  /D           Delete file transfer after saving files.\n\n",
  74.      "  /C           Confirm each file before saving.\n",
  75.      "  /N           Notify by listing files as they're saved.\n\n",
  76.      "  /R           Redirect output to file OUTPUT.CC.\n",
  77.      "  /?           Display help information.\n"
  78. };
  79. #define HELPSIZE (sizeof(HelpTable)/sizeof(HelpTable[0]))
  80.  
  81. /*---------------------------------------------------------------------------*
  82.  *                  GetTaskBuffer()                 *
  83.  *---------------------------------------------------------------------------*
  84.  * Get information about the event specified by Handle. The Task Control     *
  85.  * File is opened and read. The FileHandle returned is a normal MS-DOS file  *
  86.  * handle.                                     *
  87.  *---------------------------------------------------------------------------*
  88.  * Parameters:    int Handle - Event handle of task.                 *
  89.  *        BYTE Queue - The queue (Task, Log or Receive) of event.      *
  90.  *        char *TCFbuffer - Uninitialized ECS structure, filled with   *
  91.  *            Task Control info on return.                 *
  92.  *        int *FileHandle - Filled with DOS file handle on return.     *
  93.  * Return:    none                                 *
  94.  *---------------------------------------------------------------------------*/
  95. GetTaskBuffer(int Handle, BYTE Queue, char *TCFbuffer, int *FileHandle)
  96. {
  97.     /* Let CAS open the Task Control File. Read the contents into TCFbuffer. */
  98.     if((*FileHandle = CASOpenFile(Handle,0,Queue)) > 0) {
  99.         read(*FileHandle, TCFbuffer, sizeof(ECF));
  100.         }
  101.     else
  102.     CASError(CASNOTCF, TRUE, -(*FileHandle));
  103. }
  104.  
  105. /*---------------------------------------------------------------------------*
  106.  *               GetFileTransferBuffer()                 *
  107.  *---------------------------------------------------------------------------*
  108.  * Get information about the File Transfer Record. Offset specifies the      *
  109.  * location within the Task Control File of the FTR record. Usually, the     *
  110.  * first FTR is at offset 383 in the TCF (if no cover text). In any case,    *
  111.  * the offset of the first FTR is stored at offset 10 of the TCF. Each         *
  112.  * subsequent FTR is 128 bytes after the first.                  *
  113.  *---------------------------------------------------------------------------*
  114.  * Parameters:    long Offset - File offset to begin reading at.             *
  115.  *        char *FTRbuffer - Uninitialized FTR structure, filled with   *
  116.  *            File Transfer info on return.                 *
  117.  *        int *FileHandle - DOS file handle obtained from a call to    *
  118.  *            CASOpenFile().                         *
  119.  * Return:    none                                 *
  120.  *---------------------------------------------------------------------------*/
  121. GetFileTransferBuffer(long Offset, char *FTRbuffer, int *FileHandle)
  122. {
  123.     /* Read the File Transfer Record specified by Offset. */
  124.     lseek(*FileHandle, Offset, SEEK_SET);
  125.     read(*FileHandle, FTRbuffer, sizeof(FTR));
  126. }
  127.  
  128. /*---------------------------------------------------------------------------*
  129.  *                 OkayToMove()                     *
  130.  *---------------------------------------------------------------------------*
  131.  * OkayToMove checks for existence of FileName. If the file does not exist,  *
  132.  * the function returns TRUE.  If it exists, CAS Move Received File will     *
  133.  * fail, so the user is prompted for permission to overwrite. If permission  *
  134.  * is granted, the file is removed and the function returns true.  If the    *
  135.  * removal fails or the user does not give permission, the function returns  *
  136.  * false.                                     *
  137.  *---------------------------------------------------------------------------*
  138.  * Parameters:    char *FileName - Path and name of file to test.          *
  139.  * Return:    TRUE if it is okay to call CASMoveReceivedFile, FALSE         *
  140.  *            otherwise.                             *
  141.  *---------------------------------------------------------------------------*/
  142. int OkToMove(char *FileName)
  143. {
  144.     char answer[1];            /* Users response to confirmation quest. */
  145.  
  146.     /* Check to see if file already exists. */
  147.     if(access(FileName, 0) == 0) {
  148.     /* Confirm overwrite on existing file. */
  149.     fprintf(stderr,"File %s already exists - overwrite? (y/n)", strupr(FileName));
  150.     gets(answer);
  151.  
  152.     if(toupper(answer[0]) == 'Y') {
  153.         /* If we can't remove the existing file, don't try saving file. */
  154.         if(remove(FileName) == -1) {
  155.         CASError(CASDELJOB, FALSE, 0);
  156.         return(FALSE);
  157.         }
  158.  
  159.         /*    OK, save the file as planned. */
  160.         return(TRUE);
  161.     }
  162.     /* No permission to overwrite. */
  163.     else
  164.         return(FALSE);
  165.     }
  166.     /* File doesn't already exist - go ahead and save file. */
  167.     else {
  168.     /* User asked for confirmation first. */
  169.     if(Confirm) {
  170.         fprintf(stderr, "Save file %s? (y/n)", strupr(FileName));
  171.         gets(answer);
  172.         if(toupper(answer[0]) == 'Y')
  173.         return(TRUE);
  174.         else
  175.         return(FALSE);
  176.     }
  177.     /* Don't have to confirm - just do it. */
  178.     else
  179.         return(TRUE);
  180.     }
  181. }
  182.  
  183. /*---------------------------------------------------------------------------*
  184.  *                MoveFile()                     *
  185.  *---------------------------------------------------------------------------*
  186.  * Move all files associated with the event specified by EventHandle. The    *
  187.  * files are moved to the path NewFilePath given on the command line. Each   *
  188.  * file retains its original filename that was passed from the sending         *
  189.  * machine.                                     *
  190.  *---------------------------------------------------------------------------*
  191.  * Parameters:    int EventHandle - Event handle of task owning the file to    *
  192.  *            be moved.                             *
  193.  *        char *NewFilePath - Path name where file is to be saved. It  *
  194.  *            must not end with a filename or trialing '\'. The name   *
  195.  *            is taken from the FTR (i.e. the same name the file had   *
  196.  *            on the remote machine.                     *
  197.  *        ECF *TCFbuffer - Filled in ECS structure.             *
  198.  *        FTR *FTRbuffer - Filled in FTR structure.             *
  199.  * Return:    none                                 *
  200.  *---------------------------------------------------------------------------*/
  201. MoveFile(int EventHandle, char *NewFilePath, ECF *TCFbuffer, FTR *FTRbuffer)
  202. {
  203.     int Return;             /* Return value from CAS functions.      */
  204.     long Offset;            /* Offset of FTR in task control file.   */
  205.     int FileHandle;            /* DOS file handle (from GetTaskBuffer). */
  206.     int x;                /* Loop counter.                 */
  207.     char FileName[80];            /* Place to build the full path name.    */
  208.     char NewFileName[80];        /* Temp path name.                 */
  209.     char SFileName[80];         /* Pointer to last '\' char in filename. */
  210.  
  211.     GetTaskBuffer(EventHandle, RECEIVE_QUEUE, (char *)TCFbuffer, &FileHandle);
  212.  
  213.     /* Only File Transfers are valid here. */
  214.     if(TCFbuffer->TransferType != FILE_TRANSFER)
  215.     CASError (CASNOTFT, TRUE, 0);
  216.  
  217.     /* The first FTR is at the offset stored at FTROffset in the TCF.
  218.      * This will vary depending on if cover text was sent. */
  219.     Offset = TCFbuffer->FTROffset;
  220.  
  221.     /* For each additional received file, build a path name and move it. */
  222.     for(x = 1; x <= TCFbuffer->FileCount; x++) {
  223.  
  224.     /* Get information about the file that was transferred. */
  225.     GetFileTransferBuffer(Offset, (char *)FTRbuffer, &FileHandle);
  226.  
  227.     /* Build the full path name to the new file. */
  228.     strcpy(FileName, NewFilePath);
  229.     strcpy(SFileName, strrchr(FTRbuffer->FileName, '\\'));
  230.     if(SFileName[0] == '\0') {
  231.         if(FileName[strlen(FileName) - 1] != '\\') {
  232.         strcpy(NewFileName, "\\");
  233.         strcat(NewFileName, FTRbuffer->FileName);
  234.         }
  235.         else
  236.         strcpy(NewFileName, FTRbuffer->FileName);
  237.  
  238.         strcat(FileName, NewFileName);
  239.     }
  240.     else
  241.         strcat(FileName, SFileName);
  242.  
  243.     /* Clear temp file name. */
  244.     memset(NewFileName, 0, 80);
  245.  
  246.     /* Now check to see if the file has already been saved. */
  247.     if(FTRbuffer->FileStatus == MOVED) {
  248.         fprintf(stderr, "%s : ", strupr(FileName));
  249.         CASError(CASPRIORMOVE, FALSE, 0);
  250.     }
  251.     else {
  252.         /* Check if OK to move - if so, move it. */
  253.         if(OkToMove(FileName)) {
  254.         if(Verbose)
  255.             fprintf(stderr, "Saving %s\n", strupr(FileName));
  256.  
  257.         if((Return = CASMoveReceivedFile(EventHandle, x, FileName)) != SUCCESS)
  258.             CASError(CASMOVE, FALSE, -Return);
  259.         else
  260.             FilesMoved += 1;
  261.         }
  262.     }
  263.  
  264.     /* The next FTR is 128 bytes after the previous. */
  265.     Offset = Offset + 128;
  266.     }
  267.     close(FileHandle);
  268.  
  269.     if(Delete)
  270.     CASDeleteFile(EventHandle, 0, LOG_QUEUE);
  271. }
  272.  
  273. /*---------------------------------------------------------------------------*
  274.  *                SaveAllFiles()                     *
  275.  *---------------------------------------------------------------------------*
  276.  * Search the Receive queue for files to save. When complete, all files in   *
  277.  * the receive queue will have been moved to the directory specified by the  *
  278.  * NewFilePath parameter.                             *
  279.  *---------------------------------------------------------------------------*
  280.  * Paramters:    char *NewFilePath - Directory and drive where files are to   *
  281.  *            be moved to.                         *
  282.  *        ECF *TCFbuffer - Uninitialized ECF structure.             *
  283.  *        FTR *FTRbuffer - Uninitialized FTR structure.             *
  284.  * Return:    none                                 *
  285.  *---------------------------------------------------------------------------*/
  286. SaveAllFiles(char *NewFilePath, ECF *TCFbuffer, FTR *FTRbuffer)
  287. {
  288.     int FileHandle;            /* Open ECF file handle.             */
  289.     int EventHandle;            /* Event handle.                 */
  290.     int done = FALSE;            /* Queue processing flag.             */
  291.  
  292.     if((EventHandle = CASFindFirst(COMPLETED,SEARCH_FORWARD,RECEIVE_QUEUE)) < 0)
  293.         done = TRUE;
  294.  
  295.     while(done == FALSE) {
  296.     GetTaskBuffer(EventHandle, RECEIVE_QUEUE, (char *)TCFbuffer, &FileHandle);
  297.     if(TCFbuffer->TransferType == FILE_TRANSFER) {
  298.         close(FileHandle);
  299.         MoveFile(EventHandle, NewFilePath, TCFbuffer, FTRbuffer);
  300.     }
  301.         if ((EventHandle = CASFindNext(RECEIVE_QUEUE)) < 0)
  302.            done = TRUE;
  303.     }
  304. }
  305.  
  306. /*---------------------------------------------------------------------------*
  307.  *                     Main                     *
  308.  *---------------------------------------------------------------------------*
  309.  * Move all files from the specified event to another directory, saving      *
  310.  * them as normal DOS files. If the /A switch is given on the command line   *
  311.  * then all files (from all events) in the Receive queue are saved to that   *
  312.  * directory.                                     *
  313.  *---------------------------------------------------------------------------*
  314.  * Return: The DOS exit code is 0 if no errors are encountered, 1 for         *
  315.  *       commandline syntax errors, 2 for CCAM error, and 3 for DOS         *
  316.  *       errors.                                 *
  317.  *---------------------------------------------------------------------------*/
  318. main(int argc, char **argv)
  319. {
  320.  
  321.     int result;             /* DOS & CAS function return values.     */
  322.     char Name[80];            /* Path name from command line.         */
  323.  
  324.     argc = ParseCommand(argc, argv, SwitchTable, TABLESIZE);
  325.  
  326.     /* If help is wanted, print info and exit (with 0 exit code). */
  327.     if(Help || (argc == 1))
  328.     CASHelp(DescTable, DESCSIZE, HelpTable, HELPSIZE);
  329.  
  330.     /* Insure that the Resident Scheduler is installed. */
  331.     if((result = CASGetInstalledState()) != INSTALLED) {
  332.     if( result == NOTiOK )
  333.         CASError(CASNOHWO, TRUE, 0);
  334.     else
  335.         CASError(CASNOHWN, TRUE, 0);
  336.     }
  337.  
  338.     /* Redirect stdout to a file. */
  339.     if(RedirOut) {
  340.     if((ccout = fopen("OUTPUT.CC", "w")) == NULL)
  341.         CASError(CASOPENTEMP, TRUE, 0);
  342.     if(-1 == dup2(fileno(ccout), 1))
  343.         CASError(CASBADREDIR, TRUE, 0);
  344.     }
  345.  
  346.     /* Check to make sure that a (one only) path name was specified. */
  347.     if(argc < 2)
  348.     CASError(CASARGPATH, TRUE, 0);
  349.     else if(argc > 2)
  350.     CASError(CASARGMULTPATH, TRUE, 0);
  351.  
  352.     /* Get buffer for Task information. */
  353.     TCFbuffer = (ECF *)malloc(sizeof(ECF));
  354.     if(TCFbuffer == NULL)
  355.     CASError(CASNOMEM, TRUE, 0);
  356.  
  357.     /* Get buffer for File Transfer information. */
  358.     FTRbuffer = (FTR *)malloc(sizeof(FTR));
  359.     if(FTRbuffer == NULL)
  360.     CASError(CASNOMEM, TRUE, 0);
  361.  
  362.     /* Check for the existance of the specified path name, if ok, then
  363.      * move it. */
  364.     ++argv;
  365.     strcpy(Name, *argv);
  366.     if(access(Name, 0) == -1)
  367.     CASError(CASNOPATH, TRUE, 0);
  368.     else if(MoveAll)
  369.     SaveAllFiles(Name, TCFbuffer, FTRbuffer);
  370.     else
  371.     MoveFile(JobNo, Name, TCFbuffer, FTRbuffer);
  372.  
  373.     /* If nothing was saved - and we didn't exit due to errors, let the user
  374.        know what happened. */
  375.     if(!FilesMoved)
  376.     CASError(CASNOMOVE, TRUE, 0);
  377.     else
  378.     fprintf(stderr, "     %d files saved.\n", FilesMoved);
  379.  
  380.     exit(0);
  381. }
  382.